/**
 *  Copyright (c) 2007 - 2009 Adobe
 *  All rights reserved.
 *
 *  Permission is hereby granted, free of charge, to any person obtaining
 *  a copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included
 *  in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 *  IN THE SOFTWARE.
 */
package com.adobe.txi.todo.application
{
	import com.adobe.txi.todo.domain.TodoItem;
	import com.adobe.txi.todo.domain.TodoModel;
	
	import mx.collections.ArrayCollection;
	import mx.events.PropertyChangeEvent;

	public class TodoItemController
	{
		[MessageDispatcher]
		public var dispatcher:Function;

		[Bindable]
		public var currentTodoItemChanged:Boolean;

		[Bindable]
		public var isNewItem:Boolean;

		[Bindable]
		[CommandStatus(type="com.adobe.txi.todo.application.SaveTodoItemMessage")]
		public var saveInProgress:Boolean;

		private var _currentTodoItem:TodoItem;

		private var _todos:ArrayCollection;

		[Inject]
		public var todoModel:TodoModel;
		
		[Subscribe(objectId="currentTodoItem")]
		public function set currentTodoItem(value:TodoItem):void
		{
			//force cancel before moving to another item if that new item is different from null
			if ( value && currentTodoItemChanged && _currentTodoItem && _currentTodoItem != value)
			{
				cancel();
			}

			//keep in memory a copy of the todo item in case of revert
			todoModel.backupCurrentTodoItem();
			
			
			if(_currentTodoItem)
			{
				_currentTodoItem.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);				
			}
			
			_currentTodoItem=value;
			
			if(_currentTodoItem)
			{
				_currentTodoItem.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
			}

			//invalidate current states
			invalidateCurrentTodoItemStates();
		}

		[Bindable]
		public function get currentTodoItem():TodoItem
		{
			return _currentTodoItem;
		}

		[Subscribe(objectId="todos")]
		public function set todos(value:ArrayCollection):void
		{
			if (value && value != _todos)
			{
				_todos=value;
				currentTodoItemChanged=false;
			}
		}

		public function cancel():void
		{
			todoModel.rollbackCurrentTodoItem();
			
			invalidateCurrentTodoItemStates();
		}

		public function save():void
		{
			dispatcher(new SaveTodoItemMessage(_currentTodoItem));
		}

		[CommandComplete]
		public function saveCompleteHandler(message:SaveTodoItemMessage):void
		{
			//override the previous backup of the item with the new one.
			todoModel.backupCurrentTodoItem();
			
			//force an invalidation of the states
			invalidateCurrentTodoItemStates();
		}

		private function propertyChangeHandler(event:PropertyChangeEvent):void
		{
			//Make sure that the item modified is the currently edited item
			currentTodoItemChanged=true;
		}

		private function invalidateCurrentTodoItemStates():void
		{
			if (todoModel.currentTodoItem && todoModel.currentTodoItem.isNew())
			{
				currentTodoItemChanged=true;
				isNewItem=true;
			}
			else
			{
				currentTodoItemChanged=false;
				isNewItem=false;
			}
		}


	}
}